/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.lcm.metadata.core.refi18n;

import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.Metadata4Ref;
import com.inspur.edp.lcm.metadata.api.entity.MetadataPackage;
import com.inspur.edp.lcm.metadata.api.entity.MetadataProject;
import com.inspur.edp.lcm.metadata.api.entity.ProjectMetadataCache;
import com.inspur.edp.lcm.metadata.api.service.FileService;
import com.inspur.edp.lcm.metadata.cache.MetadataDevCacheManager;
import com.inspur.edp.lcm.metadata.common.Utils;
import com.inspur.edp.lcm.metadata.core.MetadataCoreManager;
import com.inspur.edp.lcm.metadata.core.MetadataProjectCoreService;
import com.inspur.edp.lcm.metadata.core.index.MetadataPackageIndexServiceForMaven;
import com.inspur.edp.lcm.metadata.core.index.MetadataPackageIndexServiceForPackages;
import com.inspur.edp.lcm.metadata.core.index.ProjectMetadataCacheService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class RefLocationFilter implements IRefI18nFilter {
    private final MetadataCoreManager metadataManager = new MetadataCoreManager();
    private final MetadataProjectCoreService projectService = new MetadataProjectCoreService();
    private ProjectMetadataCacheService projectMetadataCacheService;

    @Override
    public List<GspMetadata> getRefI18nMetadata(String resourceMdID, String resourceFileName, String path,
        String mavenPath, String packagePath) {
        //从工程引用范围内，查找包依赖的元数据内容
        MetadataProject metadataProject = MetadataProjectCoreService.getCurrent().getMetadataProjInfo(path);
        Utils.checkNPE(metadataProject, "获取的元数据工程信息为null，参数为projPath：" + path);

        // 从当前工程及bo下的引用的工程下搜索
        List<GspMetadata> metadataFromProjects = getMetadataFromProjects(resourceMdID, metadataProject);
        if (metadataFromProjects.size() > 0) {
            return metadataFromProjects;
        }

        // 从缓存中获取
        projectMetadataCacheService = ProjectMetadataCacheService.getNewInstance(metadataProject, path, packagePath, mavenPath);
        String metadataPackageLocation = getMetadataPackageLocationFromCache(resourceMdID, metadataProject, false, packagePath, mavenPath);
        if (metadataPackageLocation == null || metadataPackageLocation.isEmpty()) {
            metadataPackageLocation = getMetadataPackageLocationFromCache(resourceMdID, metadataProject, true, packagePath, mavenPath);
            if (metadataPackageLocation == null || metadataPackageLocation.isEmpty()) {
                metadataManager.throwMetadataNotFoundException(resourceMdID);
            }
        }

        //按照maven的查找规范查找，查找maven目录与packages目录
        //获取资源元数据所在包的信息，包括包所在的位置，元数据所处包中的位置，需要过滤具体的包中，资源元数据对应的语言包元数据，元数据文件名称.languagecode.lres(SalesOrder0426.be.en.lres)
        return GetlresMetadataFromPackage(resourceMdID, resourceFileName, metadataPackageLocation);
    }

    private String getMetadataPackageLocationFromCache(String metadataID, MetadataProject metadataProject,
        Boolean refreshIndexFlag, String packagePath, String mavenPath) {
        if (refreshIndexFlag) {
            MetadataPackageIndexServiceForPackages.getInstance(packagePath).refreshMetadataPackageIndex();
            MetadataPackageIndexServiceForMaven.getInstance(mavenPath).refreshMetadataPackageIndex();
            projectMetadataCacheService.clearCache();
        }
        projectMetadataCacheService.syncProjectMetadataCache();
        ProjectMetadataCache projectMetadataCacheMap = (ProjectMetadataCache) MetadataDevCacheManager.getProjectMetadataCacheMap(metadataProject.getProjectPath());
        return projectMetadataCacheMap.getMetadataPackageLocations().get(metadataID);
    }

    private List<GspMetadata> getMetadataFromProjects(String resourceMdID, MetadataProject metadataProject) {
        List<GspMetadata> lresMetadataList = new ArrayList<>();
        List<String> refProjPaths = new ArrayList<>();
        if (metadataProject != null) {
            refProjPaths.add(metadataProject.getProjectPath());
            projectService.getRefProjPaths(metadataProject.getProjectPath(), refProjPaths);
            FileService fileService = SpringBeanUtils.getBean(FileService.class);
            for (String projPath : refProjPaths) {
                List<GspMetadata> metadataList = metadataManager.getMetadataList(projPath);
                for (GspMetadata gspMetadata : metadataList) {
                    if (gspMetadata.getHeader().getId().equals(resourceMdID)) {
                        String resourceMdFileNameWithoutExt = fileService.getFileNameWithoutExtension(gspMetadata.getHeader().getFileName());
                        for (GspMetadata metadata : metadataList) {
                            if (metadata.getHeader().getFileName().endsWith(Utils.getLanguageMetadataFileExtention()) && metadata.getHeader().getFileName().startsWith(resourceMdFileNameWithoutExt)) {
                                GspMetadata lresMetadata = metadataManager.loadMetadata(gspMetadata.getHeader().getFileName(), gspMetadata.getRelativePath());
                                lresMetadataList.add(lresMetadata);
                            }
                        }
                        break;
                    }
                }
            }
        }
        return lresMetadataList;
    }

    private List<GspMetadata> GetlresMetadataFromPackage(String resourceMdID, String resourceMdFileName,
        String metadataPackageLocation) {
        File packageFile = new File(metadataPackageLocation);
        //必须用GetMetadataPackageInfoFromSpecPath获取包的信息
        MetadataPackage metadataPackageInfo = MetadataCoreManager.getCurrent().getMetadataPackageInfo(packageFile.getName(), packageFile.getParent());
        //根据包具体的信息，对比metadataid，找到metadataid对应元数据的相对路径，其中找语言包元数据列表
        if (metadataPackageInfo == null || metadataPackageInfo.getMetadataList() == null) {
            throw new RuntimeException("could not find reourseMetadata's metadataPackage, reoursefilename is " + resourceMdFileName);
        }

        FileService fileService = SpringBeanUtils.getBean(FileService.class);
        List<GspMetadata> lresMetadataList = new ArrayList<>();
        for (GspMetadata gspMetadata : metadataPackageInfo.getMetadataList()) {
            if (resourceMdID.equals(gspMetadata.getHeader().getId())) {
                String resourceMdFileNameWithoutExt = fileService.getFileNameWithoutExtension(gspMetadata.getHeader().getFileName());
                for (GspMetadata metadata : metadataPackageInfo.getMetadataList()) {
                    if (metadata.getHeader().getFileName().endsWith(Utils.getLanguageMetadataFileExtention()) && metadata.getHeader().getFileName().startsWith(resourceMdFileNameWithoutExt)) {
                        Metadata4Ref metadataFromPackage = MetadataCoreManager.getCurrent().getMetadataFromPackage(packageFile.getName(), packageFile.getParent(), metadata.getHeader().getId());
                        lresMetadataList.add(metadataFromPackage.getMetadata());
                    }
                }
                break;
            }
        }

        return lresMetadataList;
    }
}
